package com.gator.spring.framework.aop.aspect;

import com.gator.spring.framework.aop.intercept.PABLO_MethodInterceptor;
import com.gator.spring.framework.aop.intercept.PABLO_MethodInvocation;

import java.lang.reflect.Method;

/**
 * @Author PABLO
 * @Date 2022/5/8 17:26
 * @Desc 方法返回通知拦截器   在执行拦截器链的时候，会依次回调这里的invoke方法
 */
public class PABLO_AfterReturningAdviceInterceptor
        extends PABLO_AbstractAspectAdvice
        implements PABLO_Advice, PABLO_MethodInterceptor {
    //切点连接点，即每个method和它对应的拦截器链，这里保存是为了继续执行责任链模式，每个通知（拦截器）都是一个责任链节点
    private PABLO_JoinPoint joinPoint;

    public PABLO_AfterReturningAdviceInterceptor(Method aspectMethod, Object aspectTarget) {
        super(aspectMethod, aspectTarget);
    }

    @Override
    public Object invoke(PABLO_MethodInvocation invocation) throws Throwable {
        //如果非before，直接回调proceed，继续执行下一个拦截链，直到执行目标方法
        //等待方法栈回退，会后到这里后，retVal已经是目标方法的返回值了，再从这里依次往后直行
        Object retVal = invocation.proceed();
        this.joinPoint = invocation;
        this.afterReturning(retVal,invocation.getMethod(),invocation.getArguments(),invocation.getThis());
        return retVal;
    }

    private void afterReturning(Object retVal, Method method, Object[] arguments, Object aThis) throws Throwable {
        super.invokeAdviceMethod(this.joinPoint,retVal,null);//这里将joinPoint传入是为了从拦截器链下标的位置继续匹配对应通知（拦截器），继续执行
    }
}
